home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
system
/
ms_sh22b.zip
/
src
/
swap.asm
< prev
next >
Wrap
Assembly Source File
|
1993-12-01
|
23KB
|
1,356 lines
TITLE swap.asm
NAME swap
.8087
; MS-DOS System Function with Swaping - Front End
;
; MS-DOS System - Copyright (c) 1990,1,2 Data Logic Limited
;
; This code is subject to the following copyright restrictions:
;
; 1. Redistribution and use in source and binary forms are permitted
; provided that the above copyright notice is duplicated in the
; source form.
;
; $Header: /usr/users/istewart/src/shell/sh2.2/RCS/swap.asm,v 2.0 1992/05/21 16:49:54 Ian_Stewartson Exp $
;
; $Log: swap.asm,v $
; Revision 2.0 1992/05/21 16:49:54 Ian_Stewartson
; MS-Shell 2.0 Baseline release
;
; Revision 2.0 1992/04/13 17:39:45 Ian_Stewartson
; MS-Shell 2.0 Baseline release
;
;
; MODULE DEFINITION:
;
; This is the front end for the swapping version of system. When linked
; in, it should be the first module in the load line so that it appears in
; memory immediately after the psp. For example:
;
; link swap+x1+x2+x3+system;
;
; This module has no user changeable features. All selections are
; performed in the associated system function.
;
; If you want small model, you can only get small model data. This
; requires this module to be compiled with the -DSMALL_DATA switch to the
; assembler.
;
; More details in system.c
;
; Author:
; Ian Stewartson
; Data Logic, Queens House, Greenhill Way
; Harrow, Middlesex HA1 1YR, UK.
; istewart@datlog.co.uk or ukc!datlog!istewart
;
;
;
; Segment declarations
;
SWAP_TEXT segment word public 'CODE'
SWAP_TEXT ends
_DATA segment word public 'DATA'
_DATA ends
CONST segment word public 'CONST'
CONST ends
_BSS segment word public 'BSS'
_BSS ends
DGROUP group CONST, _BSS, _DATA
;
; Declare external functions and data
;
extrn __maperror:far
extrn _errno:word
extrn __psp:word
;
; Start of the spawn function
;
SWAP_TEXT segment
assume cs: SWAP_TEXT, ds: NOTHING, ss: DGROUP
;
; For this function, all the code and data space are in the code space
;
public _cmd_line
public _path_line
public _SW_intr
public _SW_Blocks
public _SW_fp
public _SW_EMstart
public _SW_Mode
public _SW_EMSFrame
public _SW_Int00
public _SW_Int23
public _SW_XMS_Driver
public _SW_XMS_Gversion
public _SW_XMS_Allocate
public _SW_XMS_Free
public _SW_XMS_Available
public _SW_I23_InShell
_cmd_line db 129 dup (?) ; Command line
_path_line db 80 dup (?) ; Path line
_SW_Blocks dw 0 ; Number of blocks to read/write
_SW_fp dw 0ffffH ; File ID
_SW_EMstart dd 0100000H ; Default Extended Mem start
_SW_Mode dw 0 ; Type of swapping to do
; 1 - disk
; 2 - Extended memory
; 3 - EMS driver
; 4 - XMS driver
_SW_EMSFrame dw 0 ; EMS Frame segment
_SW_intr dw 0 ; Interrupt 23 detected.
_SW_XMS_Driver dd 0 ; XMS Driver Interface
_SW_I23_InShell db 0 ; In shell flag for Interrupt 23
;
; Some addition variables
;
SW_LMstart dd 0 ; Low Mem start for Extended Mem swap
N_mcb dw 0 ; Start write address
Result dw 0 ; Return value
;
; Stack save pointers
;
S_ss dw 0 ; Save Stack pointers
S_sp dw 0
S_di dw 0 ; Save DI, SI
S_si dw 0
S_ds dw 0 ; Save the original DS
;
; Two blank FCB
;
FCB1 dw 16 dup (?)
FCB2 dw 16 dup (?)
;
; XMS Driver Move structure
;
XMS_DIF equ $
XMS_Length dd 0 ; Number of bytes
XMS_SHandle dw 0 ; Source Handler
XMS_Soffset dd 0 ; Source Offset
XMS_DHandle dw 0 ; Destination Handler
XMS_Doffset dd 0 ; Destination Offset
;
; Extended Memory Global Descriptor tables
;
org XMS_DIF
GD_table equ $
GDT_Dummy dw 4 dup (0) ; Dummy
GDT_self dw 4 dup (0) ; For self
GDT_src equ $ ; Source
dw 04000H ; Length - 16K bytes
GDT_src_low dw 0 ; Low Order address
GDT_src_high db 0 ; High Order address
db 093h ; Access Rights
dw 0 ; Reserved
GDT_dest equ $ ; Destination
dw 04000H ; Length - 16K bytes
GDT_dest_low dw 0 ; Low Order address
GDT_dest_high db 0 ; High Order address
db 093h ; Access Rights
dw 0 ; Reserved
GDT_bios dw 4 dup (0) ; Bios
GDT_stack dw 4 dup (0) ; Stack
;
; Execute interrupt structure
;
exec_parms equ $
exec_env dw 0
dw offset _cmd_line ; Command line address
exec_cseg dw ?
dw offset FCB1 ; FCB1 address
exec_f1seg dw ?
dw offset FCB2 ; FCB1 address
exec_f2seg dw ?
Swap_PANIC db 'PANIC: Swap file re-load error - REBOOT', 0aH, 0dH
db '$'
Swap_DZERO db 'PANIC: Divide by zero', 0aH, 0dH
db '$'
;
; OK - exec requires a local stack, cause some programs overwrite it
;
even
db 398 dup (0)
Local_Stack:
dw 0
;
; Code starts
;
public _SA_spawn
SA_spawn1 proc far
mov ds, word ptr cs:exec_env ; Load Env seg.
xor si, si ; Clear start offset
;
; Copy into Env Seg
;
$Copy_Env:
ifndef SMALL_DATA
les bx, dword ptr ss:[bp + 6] ; Check for end of loop
mov ax, word ptr es:[bx + 0]
or ax, word ptr es:[bx + 2]
else
mov dx, word ptr cs:S_ds ; Get original DS
mov es, dx ; and dump it in dx for later
mov bx, word ptr ss:[bp + 6] ; Check for end of loop
mov ax, word ptr es:[bx + 0]
or ax, ax
endif
je $Copy_End
;
; Save start address
;
; For small data model,the DX register contains the original DS
;
ifndef SMALL_DATA
add word ptr ss:[bp + 6], 4 ; Increment environment by 4
mov cx, word ptr es:[bx + 0] ; Load address of cur Env string
mov ax, word ptr es:[bx + 2] ; into es:bx
else
add word ptr ss:[bp + 6], 2 ; Increment environment by 2
mov cx, word ptr es:[bx + 0] ; Load address of cur Env string
mov ax, dx ; into es:bx
endif
mov es, ax
mov bx, cx
;
; Copy this value
;
$Copy_Val:
mov al, byte ptr es:[bx] ; Copy across
mov byte ptr ds:[si], al
inc bx ; Increment pointers
inc si
or al, al
jne $Copy_Val
jmp $Copy_Env
;
; Set up exec parameter block - DS is on stack
;
$Copy_End:
xor ax, ax
mov word ptr ds:[si], ax ; Terminate environment
add si, 2
;
; Set up new program length
;
add si, 16 ; Round up paras
mov dx, si ; Save end offset in DX
mov bx, ds
mov cl, 4
shr si, cl ; # paras used by Env
add si, bx ; End para number
mov bx, word ptr cs:N_mcb ; Load our MCB address in BX
mov ax, bx
inc ax
sub si, ax
mov cx, si ; Save new max paras in CX
;
; Use interrupt 4a to shrink memory. First release all memory above us.
;
push ax
push cx ; Save Max paras and location
mov ds, bx ; Set up the segement for MCB
mov cx, word ptr ds:3 ; Get the MCB length
; Are we the only one in the chain?
cmp byte ptr ds:0, 'Z' ; End of chain ?
jz $Shrink_First
;
; Loop round releasing memory blocks
;
; CX - original length of block;
; DS - segement of the previous block
;
$Shrink_Next:
mov ax, ds ; Move to the next block
add cx, ax
inc cx
mov ds, cx
cmp byte ptr ds:0, 'Z' ; End of chain ?
jz $Shrink_First
mov cx, word ptr ds:3 ; Save the length of this block
mov ax, ds ; Advance to the block itself
inc ax
mov es, ax ; Set up Block address
mov ah, 049H
int 021H
jmp $Shrink_Next
;
; Shrink the PSP segment
;
$Shrink_First:
pop cx
pop ax
mov es, ax ; Set PSP address
mov bx, cx ; Set max length
mov ah, 04aH
int 021H
;
; Execute function
;
mov word ptr cs: S_sp, sp ; Save the current stack
mov word ptr cs: S_ss, ss
;
; Move to the local stack so that it doesn't get overwritten.
;
mov ax, cs
cli
mov sp, offset Local_Stack
mov ss, ax
sti
; Clear out Interrupts
mov ah, 00bH ; Check Keyboard status
int 021H
;
; Check for interrupt 23 detected
;
mov ax, word ptr cs:_SW_intr
or ax, ax
jz $I23_Cf ; No - continue;
;
; Interrupt 23 detected - abort
;
mov ax, cs ; Set up for reload
cli
mov sp, offset Local_Stack
mov ss, ax
sti
mov ds, word ptr cs:S_ds ; Restore DS
xor ax, ax
jmp $Exec_Complete
;
; No interrupts - continue
;
$I23_Cf:
mov ax, cs ; Set up segments
mov es, ax
mov ds, ax
mov ax, 04b00H ; Load and execute function
mov dx, offset _path_line ; Load path
mov bx, offset exec_parms ; Load the execute structure
mov byte ptr cs:_SW_I23_InShell, 1 ; Set not shell flag
int 021H
mov byte ptr cs:_SW_I23_InShell, 0 ; Set in shell flag
; Disable interrupts while we restore the stack to the local one
mov ax, cs
cli
mov sp, offset Local_Stack
mov ss, ax
sti
;
; Did an error occur?
;
jnc $Exec_OK
;